package dao

import (
	"encoding/json"
	"fmt"
	"gorm.io/gorm"
	"log"
	"order_srv/basic/config"
	inits "order_srv/basic/init"
	"order_srv/handler/models"
	"time"
)

// 交易同步消息结构体
type TransactionSyncMessage struct {
	OrderID         uint32    `json:"order_id"`
	OrderSn         string    `json:"order_sn"`
	UserID          uint32    `json:"user_id"`
	DriverID        uint32    `json:"driver_id"`
	Amount          float64   `json:"amount"`
	PlatformFee     float64   `json:"platform_fee"`
	DriverIncome    float64   `json:"driver_income"`
	PaymentMethod   int8      `json:"payment_method"`
	TransactionTime time.Time `json:"transaction_time"`
	OrderTime       time.Time `json:"order_time"`
	OrderStatus     int8      `json:"order_status"`
	Distance        float64   `json:"distance"`
	// 增加详细信息字段
	StartLocation    string    `json:"start_location"`
	EndLocation      string    `json:"end_location"`
	CarTypeID        int8      `json:"car_type_id"`
	ServiceStartTime time.Time `json:"service_start_time"`
	ServiceEndTime   time.Time `json:"service_end_time"`
	// 费用明细
	PricingDetails PricingDetails `json:"pricing_details"`
}

// 费用明细结构体
type PricingDetails struct {
	StartingPrice   float64 `json:"starting_price"`
	MileageFee      float64 `json:"mileage_fee"`
	DurationFee     float64 `json:"duration_fee"`
	LongDistanceFee float64 `json:"long_distance_fee"`
	BridgeFee       float64 `json:"bridge_fee"`
	NightServiceFee float64 `json:"night_service_fee"`
	ParkingFee      float64 `json:"parking_fee"`
	OtherFee        float64 `json:"other_fee"`
}

// SyncTransactionToCentralServer 实时同步交易信息到中央服务器和财务对账表
func SyncTransactionToCentralServer(orderID uint32) error {
	// 1. 查询订单详细信息
	var order models.Orders
	if err := order.GetOrderInfo(int(orderID)); err != nil {
		log.Printf("查询订单信息失败: %v", err)
		return err
	}

	// 2. 计算平台费用和司机收入（根据项目中财务对账的逻辑，平台通常收取20%的服务费）
	// 检查订单价格是否为0，如果为0则使用默认值
	orderPrice := order.Price
	if orderPrice <= 0 {
		log.Printf("警告：订单ID=%d的价格为0，使用默认价格15.0", order.Id)
		orderPrice = 15.0
	}
	platformFee := orderPrice * 0.2
	driverIncome := orderPrice * 0.8

	// 3. 构建交易同步消息
	// 检查PayTime是否为空，如果为空则使用当前时间
	transactionTime := order.PayTime
	if transactionTime.IsZero() {
		transactionTime = time.Now()
	}

	// 查询费用明细信息
	pricingInfo := &models.PricingInformation{}
	pricingErr := pricingInfo.PricingInformationOrderId(uint64(order.Id))

	// 构建费用明细对象
	pricingDetails := PricingDetails{}
	if pricingErr == nil {
		pricingDetails = PricingDetails{
			StartingPrice:   pricingInfo.PricesStarting,
			MileageFee:      pricingInfo.MileageFee,
			DurationFee:     pricingInfo.DurationFee,
			LongDistanceFee: pricingInfo.LongDistance,
			BridgeFee:       pricingInfo.Bridge,
			NightServiceFee: pricingInfo.NightServiceFee,
			ParkingFee:      pricingInfo.ParkingFee,
			OtherFee:        pricingInfo.Other,
		}
	} else {
		log.Printf("查询订单ID=%d的费用明细失败: %v，将使用默认值", orderID, pricingErr)
	}

	syncMessage := TransactionSyncMessage{
		OrderID:         order.Id,
		OrderSn:         order.OrderSn,
		UserID:          order.UserId,
		DriverID:        order.DriverId,
		Amount:          orderPrice, // 使用校正后的价格
		PlatformFee:     platformFee,
		DriverIncome:    driverIncome,
		PaymentMethod:   order.PayWay,
		TransactionTime: transactionTime,
		OrderTime:       order.CreateAt,
		OrderStatus:     order.OrderStatus,
		Distance:        order.Distance,
		// 添加详细信息
		StartLocation:    order.StartLoc,
		EndLocation:      order.EndLoc,
		CarTypeID:        order.CarTypeId,
		ServiceStartTime: order.ServiceStartTime,
		ServiceEndTime:   order.ServiceEndTime,
		PricingDetails:   pricingDetails,
	}

	// 4. 将消息序列化为JSON
	messageJSON, err := json.Marshal(syncMessage)
	if err != nil {
		log.Printf("序列化交易消息失败: %v", err)
		return err
	}

	// 5. 使用RabbitMQ发送消息到中央服务器
	// 创建一个专用的交易同步队列
	rmq := inits.NewRabbitMQSimple("transaction_sync_queue")
	defer rmq.Destory()

	// 发送消息
	success, err := rmq.PublishSimple(messageJSON)
	if err != nil {
		log.Printf("发送交易同步消息失败: %v", err)
		// 注意：即使消息队列发送失败，我们仍然继续将数据写入财务对账表
	}

	if success {
		log.Printf("成功同步订单ID=%d的交易信息到中央服务器", orderID)
	}

	// 6. 将交易信息写入财务对账表
	// 使用事务确保数据一致性
	if err := config.DB.Transaction(func(tx *gorm.DB) error {
		// 构建财务对账记录 - 注意字段类型要匹配数据库定义
		// 添加更详细的备注信息
		remark := "订单支付完成自动生成"
		if pricingErr == nil {
			remark += fmt.Sprintf("；费用明细：起步价%.2f元,里程费%.2f元,时长费%.2f元",
				pricingInfo.PricesStarting, pricingInfo.MileageFee, pricingInfo.DurationFee)
		}

		financialRecord := &models.FinancialReconciliation{
			OrderId:         order.Id,
			OrderSn:         order.OrderSn,
			TransactionType: 1,                           // 1-收入
			Amount:          float64(orderPrice * 100),   // 转换为分（数据库会存为decimal(10,2)）- 使用校正后的价格
			PlatformRevenue: float64(platformFee * 100),  // 转换为分
			DriverRevenue:   float64(driverIncome * 100), // 转换为分
			Fee:             float64(platformFee * 100),  // 服务费同平台收入
			Status:          1,                           // 1-待对账
			TransactionTime: transactionTime,             // 使用有效时间
			CreateAt:        time.Now(),
			UpdateAt:        time.Now(),
			Remark:          remark,
			PayWay:          uint8(order.PayWay),
			IsActive:        1, // 1表示启用（uint8类型）
		}

		// 在事务中创建财务对账记录
		if err := financialRecord.CreateFinancialReconciliation(); err != nil {
			log.Printf("写入财务对账表失败: %v", err)
			return err
		}

		log.Printf("成功将订单ID=%d的交易信息写入财务对账表", orderID)
		return nil
	}); err != nil {
		log.Printf("财务对账表事务处理失败: %v", err)
		// 注意：即使数据库操作失败，我们也不返回错误，因为主要功能（订单状态更新）已经完成
		// 在实际应用中，可以考虑添加重试机制或告警
	}

	return nil
}
